<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">

<head>
<meta charset="UTF-8" />
<title>jedis gui</title>
<link rel="shortcut icon" href="./image/redis.png" type="image/png">
<link rel="stylesheet" type="text/css" href="./css/common.css" />
<link rel="stylesheet" type="text/css"
	href="./css/animate.3.7.0.min.css">
<link rel="stylesheet" type="text/css" href="./css/jedis-gui.css" />
</head>

<body>
	<div id="redisManager" class="operateWindows flexContainer" v-if="isLoadingComplete">
		<!-- 全局的loading动画 -->
		<div v-bind:class = "{globalCover:true, dismiss : !displayLoadingAnimation}">
			<div v-bind:class="{globalLoading:true, globalLodingPlay:displayLoadingAnimation,
			globalLodingPaused:!displayLoadingAnimation}"></div>
		</div>
		<!-- 全局的toast提示 -->
		<div class="globalTaostDiv">
			<div
			v-for="(toast,index) in toastMessages"
			v-bind:class="{taostItem:true, successMsg: toast.type > 0, failedMsg: toast.type < 0, slideInRight: true}">
			{{toast.message}}
			<div class="closeBtn" @click="removeTaost(index)">+</div>
			</div>
		</div>
		<!-- redis服务器信息 -->
		<div class="redisInfoBtn" title ="点击查看系统信息" @click="refreshRedisServerInfo">i</div>
		<div class = "serverInfo" v-show="redisserverInfoDisplay"
		 v-bind:class="{slideInDown : refreshRedisServerInfo, slideOutUp : !refreshRedisServerInfo}">
			<div class = "infoHeader">
				<div class="headerTitle"
				title="点击刷新系统信息"
				@click="refreshRedisServerInfo">{{redisInfoPanelTitle}}</div>
				<div class="headerCloseBtn" v-show="redisserverInfoDisplay" @click = "hideInfoBody">x</div>
			</div>
			<div class = "infoBody" v-if="redisServerInfo.Server">
				<div v-for="(v, k) in redisServerInfo">
					<div class = "infoBodyHeader">{{k}}</div>
					<div class="redisInfoBox">
						<div v-for="(itemv, itemk) in v"><span>{{itemk}}</span>&nbsp;:&nbsp;{{itemv}}</div>
					</div>
				</div>
			</div>
		</div>
		<!-- redis key添加窗口 -->
		<div class="addWindowContainer" v-bind:class="{dismiss : !addKeyWindow}">
			<div class="addWindow">
				<div class="addWindowHeader"></div>
				<div class="addWindowBody">
					<div class="form-input">
						<span>key : </span><input v-model="addKeyAndValue.key" />
					</div>
					<div class="form-input">
						<span>type : </span>
						<select v-model="addKeyAndValue.type">
						    <option disabled value="">请选择</option>
							<option v-for="(op, index) in keyType">{{op}}</option>
						</select>
					</div>
					<div class="form-input" v-show="addKeyAndValue.type == 'zset'">
						<span>score : </span><input type="number" v-model="addKeyAndValue.score"></input>
					</div>
					<div class="form-input" v-show="addKeyAndValue.type == 'hash'">
						<span>field : </span><input  v-model="addKeyAndValue.field"></input>
					</div>
					<div class="form-input">
						<span>value : </span><textarea v-model="addKeyAndValue.value"></textarea>
					</div>
				</div>
				<div class="addWindowFooter">
					<button class="success" @click="performAddKeyAction">确定</button>&nbsp;<button @click="hiddenAddKeyWindow">取消</button>
				</div>
			</div>
		</div>
		<!-- redis host添加弹出窗口 -->
		<div class="addWindowContainer" v-bind:class="{dismiss : !addWindow}">
			<div class="addWindow">
				<div class="addWindowHeader"></div>
				<div class="addWindowBody">
					<div class="form-input">
					<span>redis信息&nbsp;:&nbsp;</span>
					<!--<input class="myinput" v-model="addHostInfo.redisInfoStr" />-->
					<span><input class="myinput" style="width:100px !important;" placeholder="host" v-model="inputHostInfo.host" />:
						<input class="myinput"  style="width:100px !important;" placeholder="port" v-model="inputHostInfo.port" />@
						<input class="myinput" style="width:100px !important;" placeholder="password" v-model="inputHostInfo.password" />/
						<input class="myinput" style="width:100px !important;" placeholder="alias" v-model="inputHostInfo.alias" /></span>
					</div>
					<div class="form-input" style ="text-align: left;">
						<span>添加实例说明: [host]:[port]@[pass]/[name]</span><br>
						<span>例&emsp;&emsp;&emsp;&emsp;如: 127.0.0.1:6379@Test/LocalRedis</span><br>
					</div>
				</div>
				<div class="addWindowFooter">
					<button class="success" @click="performAddHostAction">确定</button>&nbsp;<button @click="hiddenAddWindow">取消</button>
				</div>
			</div>
		</div>
		<!-- redis key 查看弹出窗口 -->
		<div class="popWindow"
			v-bind:class="{dismiss : !popWindow.windowStatus}">
			<div v-bind:class="{popDialog : popWindow.windowType == 0, popInfoWindow : popWindow.windowType == 1,
			fadeDownIn : popWindow.windowStatus, fadeUpOut : !popWindow.windowStatus}">
				<div class="dialogHeader">{{popWindow.windowTitle}}</div>
				<div class="dialogBody">
					<div class="keyspaceinfo">
						<span>{{viewData.type + " [" +viewData.size+ "]"}} : </span>
						<input disabled="disabled" v-model="viewData.key" style="min-width:300px;max-width : 500px;"/>
						&nbsp;&nbsp;<span>TTL : {{viewData.ttl}}</span>
					</div>
					<!-- 普通string类型数据 -->
					<div class="strView" v-if="popWindow.windowContentType == 0">
						<div class="updateActionBar" v-show="popWindow.windowContent==popWindow.windowContentNew">
							<button @click="updateStringVal">更新</button>
						</div>
						<textarea rows="20" cols="100" style="width: 100%;height:70%;"
						v-model="popWindow.windowContentNew"></textarea>
					</div>
					<!-- 集合数据 -->
					<div class="tableView" v-if="popWindow.windowContentType == 1">
						<!-- add list elment -->
						<div class="addValueDiv listAddDiv" v-if="viewData.type=='list'">
							<span>value</span>&nbsp;:&nbsp;<input class="myinput" v-model="viewData.newValue"/>&nbsp;&nbsp;
							<button @click="addValue">添加</button>
						</div>
						<!-- add hash field and value -->
						<div class="addValueDiv hashAddDiv" v-if="viewData.type=='hash'">
							<span>field</span>&nbsp;:&nbsp;<input class="myinput" v-model="viewData.newField"/>&nbsp;&nbsp;
							<span>value</span>&nbsp;:&nbsp;<input class="myinput" v-model="viewData.newValue"/>&nbsp;&nbsp;
							<button @click="addValue">添加</button>
						</div>
						<!-- add zset elment and score -->
						<div class="addValueDiv zsetAddDiv" v-if="viewData.type=='zset'">
							<span>score</span>&nbsp;:&nbsp;<input class="myinput" type="number" v-model="viewData.newScore"/>&nbsp;&nbsp;
							<span>value</span>&nbsp;:&nbsp;<input class="myinput" v-model="viewData.newValue"/>&nbsp;&nbsp;
							<button @click="addValue">添加</button>
						</div>
						<!-- add set elment -->
						<div class="addValueDiv setAddDiv" v-if="viewData.type=='set'">
							<span>value</span>&nbsp;:&nbsp;<input class="myinput" v-model="viewData.newValue"/>&nbsp;&nbsp;
							<button @click="addValue">添加</button>
						</div>
						<table class="mytable">
							<!-- <thead>
								<tr>
									<th v-bind:colspan="typeAndContainer[viewData.type].tdcount + 1">
									<div class="flexContainer">
										<div  v-for="header in typeAndContainer[viewData.type].ths" class = "flex-column">{{header}}</div>
									</div>
									</th>
								</tr>
							</thead> -->
							<tbody>
								<!-- 是否显示搜索框 -->
								<tr v-if="typeAndContainer[viewData.type].searchInput">
									<td v-bind:colspan="typeAndContainer[viewData.type].tdcount + 1">
									<input class="myinput" style = "height: 40px;width:90%;"
										v-model="viewData.searchKey"
										@keyup.enter="searchFieldByKey" placeholder="请输入要查询的field" />
									</td>
								</tr>
								<!-- 展示非zset和list类型的数据 -->
								<div v-if="viewData.type!='zset' && viewData.type!='list' && popWindow.windowContent['result'] !='undefined'">
								<tr class="activetr notzset"
									v-for="(key, index) in popWindow.windowContent.result">
									<td class="rowNumber" v-bind:colspan="typeAndContainer[viewData.type].tdcount + 1">
										<div class="flexContainer">
											<div class = "flex-column" style="min-width:30px;max-width:50px;">{{index + 1}}</div>
											<div v-if="typeof(key)=='object'" class = "flex-column"
											v-for="(k,v, i) in key" style="max-width:300px;">{{v}}</div>
											<div v-if="typeof(key)=='object'" class = "flex-column"
											@dbclick="openUpdateWindow(key)" v-for="(k,v, i) in key">{{k}}</div>
											<div class = "flex-column" v-if="typeof(key)=='string'"
											@dbclick="openUpdateWindow(key)">{{key}}</div>
											<div class = "flex-column" style="max-width: 90px;text-align:center;">
												<button class="dangerous" @click="deleteByField(key, index)">
												{{defaultBtnStatus.btnStatusDesc}}
												</button>
											</div>
										</div>
									</td>
								</tr>
								</div>
								<!-- 展示zset类型的数据 -->
								<tr class="activetr zset"
									v-if="viewData.type=='zset'"
									v-for="(key, index) in popWindow.windowContent">
									<td class="rowNumber" v-bind:colspan="typeAndContainer[viewData.type].tdcount + 1">
										<div class="flexContainer">
											<div class = "flex-column" style="min-width:30px;max-width:50px;">{{index + 1}}</div>
											<div class = "flex-column" style="max-width: 200px;">{{key.score}}</div>
											<div class="flex-column" @dbclick="openUpdateWindow(key)">{{key.element}}</div>
											<div class = "flex-column" style="max-width: 90px;text-align:center;">
												<button class="dangerous" @click="deleteByElement(key, index)">
												{{defaultBtnStatus.btnStatusDesc}}
												</button>
											</div>
										</div>
									</td>
								</tr>
								<!-- 展示list类型的数据 -->
								<tr class="activetr list"
									v-if="viewData.type=='list'"
									v-for="(key, index) in popWindow.windowContent">
									<td class="rowNumber" v-bind:colspan="typeAndContainer[viewData.type].tdcount + 1">
										<div class="flexContainer">
											<div class = "flex-column" style="min-width:30px;max-width:50px;">{{index + 1}}</div>
											<div class="flex-column">{{key}}</div>
											<div class = "flex-column" style="max-width: 90px;text-align:center;">
											<button class="dangerous" @click="deleteByIndex(key, index)">
											{{defaultBtnStatus.btnStatusDesc}}
											</button>
											</div>
										</div>
									</td>
								</tr>
							</tbody>
							<tfoot>
								<tr>
									<td v-bind:colspan="typeAndContainer[viewData.type].tdcount + 1">
										<button v-if="(viewData.type=='hash' || viewData.type=='set')
										&& popWindow.windowContentCursor > 0"
											v-on:click="loadMoreValues">加载更多</button>
										<button v-if="(viewData.type!='hash' && viewData.type!='set')
										&& popWindow.windowContent.length < viewData.size"
											v-on:click="loadMoreValues">加载更多</button>
									</td>
								</tr>
							</tfoot>
						</table>
					</div>
				</div>
				<div class="dialogFooter">
					<button class="dangerous" @click="hiddenPopWindow">关闭</button>
					<button @click="keyValueRefresh">刷新</button>
				</div>
			</div>
		</div>
		<div v-bind:class="{hideSideDivBtn: showHostList, showSideDivBtn: !showHostList}" @click="toggleSideHostDiv"></div>
		<!-- redis host列表 -->
		<div v-bind:class="{flexColumnNopadding:true, dismiss: !showHostList}" style="min-width: 70px;max-width: 200px;border-right:solid 1px #e6e6e6;">
			<div style="position: relative;" v-for="(host, index) in hostList">
				<div @click="changeHost(index)"
			v-bind:class="{ connectedHostFont: index == currentHostIndex, hostItem: true}"
				v-bind:title="host.host+':'+host.port">{{host.hostname }}</div>
				<div v-bind:class="{rightClickDiv:true, dismiss : !editStatus}">
					<ul>
						<li class="dangerous" @click="removeHostByIndex(index)">删除</li>
					</ul>
				</div>
			</div>
			<div class="buttonGroup">
				<div v-bind:class="{buttonItem : true, halfWidth : true, dismiss : editStatus}" @click="showAddWindows">新增连接</div>
				<div v-bind:class="{buttonItem : true, halfWidth : true, dismiss : editStatus}" @click="turnToEditModel">编辑连接</div>
				<div v-bind:class="{buttonItem : true, fullWidth : true, dismiss : !editStatus}" @click="turnToComplete">完成</div>
			</div>
		</div>
		<!-- redis 数据查看区域 -->
		<div class="operateDiv flexColumnNopadding" style="min-width: 300px;" v-bind:disabled="!functionClickable">
			<div class="databasebar">
				<div v-for="database in 16"
					v-bind:class="{ selectedDatabase: (database-1) == currentDatabseIndex, databasediv : true, floatDiv: true }"
					@click="changeDataBase(database-1)">
					{{database - 1}} <br>
				</div>
				<div v-for="database in 16" class="keysInfo floatDiv">
					{{currentHostKeySpace[database-1] ?
					currentHostKeySpace[database-1].keys : 0}} <br>
				</div>
			</div>
			<div class="redisDatas" v-if="hostList[currentHostIndex]">
				<!--<span class="addKey" @click="openAddKeyWindow">+</span>-->
				<table class="mytable">
					<thead>
						<tr>
							<th>row</th>
							<th>key</th>
							<th>action</th>
							<th class="addKeyCopy" @click="openAddKeyWindow">+</th>
						</tr>
					</thead>
					<tbody>
						<tr>
							<td colspan="3">
							<input class="myinput" style="height: 40px;width:90%;"
								v-model="hostList[currentHostIndex].searchKey"
								@keyup.enter="searchByKey" placeholder="请输入要查询的key" />
							<div class = "recentSearchPattern" v-if="recentSearchList && recentSearchList.length > 0">
							<span>最近搜索</span>:
							<div class="flexContainer">
								<div class = "flex-column clearRecentBtn" @click="clearRecentHistory" style = "max-width:60px;">
									清除
								</div>
								<div class = "flex-column recentSearchValue slideInLeft"
								v-for=" searchpattern in recentSearchList"
								@click="searchByRecent(searchpattern)"
								v-bind:title="searchpattern">{{searchpattern}}</div>
							</div>
							</div>
							</td>
						</tr>
						<tr class="activetr"
							v-for="(key, index) in hostList[currentHostIndex].datas.datalist">
							<td class="rowNumber"  colspan="4">
							<div class="flexContainer">
								<div class = "flex-column" style="min-width:30px;max-width:60px;">{{index + 1}}</div>
								<div class = "flex-column hoverCursor"  @dblclick="viewByKey(key, index)">{{key}}</div>
								<div class = "flex-column" style="min-width:80px;max-width:200px;text-align:center;">
								<button class="dangerous" @click="deleteByKey(key, index)">
								{{defaultBtnStatus.btnStatusDesc}}
								</button>
								&nbsp;
								<button class="success" @click="viewByKey(key, index)">查看</button>
								</div>
							</div>
							</td>
						</tr>
					</tbody>
					<tfoot>
						<tr>
							<td colspan="4">
								<!--
									<button @click="deleteByKey(key)">&larr;</button>
								&nbsp;&nbsp;
								<button @click="viewByKey(key)">&rarr;</button>
								&nbsp;&nbsp;
								-->
								<div v-if="hostList[currentHostIndex] && hostList[currentHostIndex].datas != 'undefined'">
								<button v-show="hostList[currentHostIndex].datas.nextIndex > 0"
									v-on:click="loadMoreKeys">加载更多</button>
								<button @click="refreshDatabase">刷新</button>
								</div>
							</td>
						</tr>
					</tfoot>
				</table>
			</div>
		</div>
	</div>
</body>
<!-- 开发环境版本，包含了有帮助的命令行警告 -->
<script src="./js/vue.2.5.17.js"></script>
<script src="./js/axios.0.12.0.min.js"></script>
<script src="./js/common.js"></script>
<script type="text/javascript">
	const wsHost = "ws://localhost:8788";
	var openWindow = function(type, title, content) {
		return {
			windowTitle: title,
			windowStatus: true,
			windowContent: {result:[]},
			windowAction:-1,
			windowType: type
		};
	};
	var closeWindow = function(action) {
		return {
			windowStatus: false,
			windowAction: action
		};
	};
	var getDeleteAction = function(btnIndex, btnActionHistory) {
		return btnActionHistory[btnIndex];
	}
	var addDeleteAction = function(btnIndex, btnActionHistory) {
		btnActionHistory[btnIndex] = btnIndex;
	}
	var removeDeleteAction = function(btnIndex, btnActionHistory) {
		delete btnActionHistory[btnIndex];
	}
	var CommonUtilApp = new Vue({
		el: "#redisManager",
		data: {
			hostChangeStatus: false,
			dataBaseChangeStatus: false,
			ws: null,
			wsCommand: {
				getKeySpaceInfo: {"command":"KEYSPACE_INFO","value":"", "time":new Date()},
				getHostInfo: {"command":"HOST_INFO","value":"test", "time":new Date()}
			},
			wsRefresher: [],
			tabRefresher: [],
			showHostList: true,
			isLoadingComplete: false,
			appName: "redis 操作面板",
			currentHostIndex: -1,
			currentDatabseIndex: 0,
			functionClickable: true,
			currentHostKeySpace: {},
			keyType: ["string", "list", "set", "zset", "hash"],
			addKeyAndValue: {
				key: "", type: "", value: "", field: "", score: 0, expire: -1
			},
			viewData: {
				type: "", key: "", ttl: -1, size: 0, searchKey:"", newValue:"", newScore:"", newField:""
			},
			popWindow:{
				windowTitle:"", windowStatus:false, windowContent:"", windowContentNew:"", windowContentCursor:0,
				windowContentType: 0, windowAction:-1, windowType: 0
			},
			editStatus: false,
			addWindow: false,
			addKeyWindow: false,
			typeAndContainer: typeAndContainer,
			defaultBtnStatus : {
				btnStatus : 0,
				btnStatusDesc : "删除",
				targetIndex: -1
			},
			confirmBtnStatus : {
				btnStatus : 1,
				btnStatusDesc : "确认删除",
				targetIndex: -1
			},
			btnActionHistory : {},
			addHostInfo: defaultHostInfo,
			inputHostInfo: {
				host: "localhost",
				port: 6379,
				password: "",
				alias: "localhost"
			},
			hostList: [],
			keyAndType: {},
			toastMessages: [],
			redisInfoPanelTitle: "系统信息",
			redisServerInfo: {titleMessage:"i"},
			redisserverInfoDisplay: false,
			displayLoadingAnimation: true,
			recentSearchList: []
		},
		created: function () {
			var saveHosts = localStorage.getItem(storageHostKey);
			if (saveHosts && saveHosts.length > 0) {
				var parsedHosts = JSON.parse(saveHosts);
				this.hostList = parsedHosts;
				var hosts = parsedHosts;
				var hostCount = parsedHosts.length;
				for (var i = 0; i < hostCount; i++) {
					if (hosts[i].selected) {
						this.currentHostIndex = i;
						this.currentDatabseIndex = [i].db;
						break;
					}
				}
			}
			this.displayLoadingAnimation = false;
			this.isLoadingComplete = true;
			let that = this;
			setTimeout(function() {
				// 初始化一个websocket连接
				that.ws = new WebSocket(wsHost);
				that.ws.onopen = function(evt) {
					console.log("[" +that.ws.readyState+ "] Connection open ...");
				};
				that.ws.onmessage = function(evt) {
					// console.log( "[" +that.ws.readyState+ "] Received Message: " + evt.data);
					let dataObj = JSON.parse(evt.data);
					if (dataObj && dataObj.code === '0' && dataObj.commandName) {
						let responseData = dataObj.data;
						switch (dataObj.commandName) {
							case "KEYSPACE_INFO":
								that.currentHostKeySpace = responseData;
								break;
							case "HOST_INFO":
								that.redisServerInfo = responseData;
								break;
							default:
								console.warn("not config command value");
								break;
						}
					}
				};
				that.ws.onclose = function(evt) {
					console.log("[" +that.ws.readyState+ "] Connection closed.");
				};
			}, 20);

			let keySpaceRefresher = setInterval(function() {
				if (that.ws && that.ws.readyState === 1) {
					that.wsCommand.getKeySpaceInfo.time = new Date();
					that.wsCommand.getHostInfo.time = new Date();
					that.ws.send(JSON.stringify(that.wsCommand.getKeySpaceInfo));
					if (that.redisserverInfoDisplay) {
						that.ws.send(JSON.stringify(that.wsCommand.getHostInfo));
					}
				}
			}, 10000, 100);
			that.wsRefresher.push(keySpaceRefresher);
		},
		methods: {
			toggleSideHostDiv: function() {
				this.showHostList = !this.showHostList;
			},
			removeTaost: function (index) {
				if (this.toastMessages[index]) {
					this.toastMessages.splice(index, 1);
				}
			},
			showAddWindows: function () {
				this.addWindow = true;
			},
			hiddenPopWindow: function () {
				this.popWindow = closeWindow(0);
			},
			hiddenAddWindow: function () {
				this.addWindow = false;
			},
			removeHostByIndex: function(index) {
				var confirmResult = confirm("确认删除？");
				if (!confirmResult) {
					return;
				}
				this.hostList.splice(index, 1);
				localStorage.setItem(storageHostKey, JSON.stringify(this.hostList));
			},
			openAddKeyWindow: function () {
				openAddKeyWindow(this);
			},
			hiddenAddKeyWindow: function () {
				this.addKeyWindow = false;
			},
			performAddKeyAction: function () {
				var redisVue = this;
				if (redisVue.addKeyAndValue.key.length == 0) {
					alert("请输入要添加的key!");
					return;
				}
				if (redisVue.addKeyAndValue.type.length == 0) {
					alert("请选择数据类型!");
					return;
				}
				if (redisVue.addKeyAndValue.value.length == 0) {
					alert("请输入要添加的value!");
					return;
				}
				axios({
				    method:"post",
				    url:hostname + "/jedis/addRedisKey/" + redisVue.addKeyAndValue.type,
				    data:redisVue.addKeyAndValue
				}).then(function (res) {
					this.addKeyWindow = false;
				    if (res.data) {
				    	addSuccessTaost(redisVue, "操作成功");
				    } else {
				    	addErrorTaost(redisVue, "操作失败");
				    }
				    initHostDataBase(redisVue, redisVue.currentDatabseIndex);
				    refreshRedisKeyspace(redisVue);
				})
			},
			performAddHostAction: function () {
				//addRedisHostStr(this, this.addHostInfo.redisInfoStr);
				//addRedisHost(this);
				addRedisHostByInput(this);
			},
			turnToEditModel: function () {
				this.editStatus = true;
			},
			turnToComplete: function () {
				this.editStatus = false;
			},
			refreshRedisServerInfo: function () {
				var vm = this;
				vm.displayLoadingAnimation = true;
				axios.get(hostname + "/jedis/info")
				.then(function (response) {
					vm.redisServerInfo = response.data;
					//vm.redisServerInfo["titleMessage"] = "系统信息";
					vm.redisserverInfoDisplay = true;
					vm.displayLoadingAnimation = false;
				})
				.catch(function (error) {
					addErrorTaost(vm, 'Error! Could not reach the API. ' + error);
				});
				//axios.get(hostname + "/jedis/fetchSlowlog")
				//.then(function (response) {
				//	console.dir(response);
				//})
				//.catch(function (error) {
				//	addErrorTaost(vm, 'Error! Could not reach the API. ' + error);
				//});
			},
			hideInfoBody: function () {
				this.redisserverInfoDisplay = false;
				this.redisServerInfo["titleMessage"] = "i";
			},
			clearRecentHistory: function() {
				clearRecentHistoryCach(this);
			},
			changeHost: function (index) {
				var redisVue = this;
				redisVue.functionClickable = false;
				var selectHost = redisVue.hostList[index];
				var params = new URLSearchParams();
				params.append('host', selectHost.host);
				params.append('port', selectHost.port);
				params.append("db", selectHost.db);
				params.append("pass", selectHost.pass);
				axios.post(hostname + "/jedis/changeRedisHost", params)
				.then(function (response) {
					if (response.data) {
						for (var i = 0; i < redisVue.hostList.length; i++) {
							redisVue.hostList[i].selected = false;
						}
						selectHost.selected = true;
						redisVue.currentHostIndex = index;
						redisVue.currentDatabseIndex = selectHost.db;
						refreshRedisKeyspace(redisVue);
						initHostDataBase(redisVue, 0);
						redisVue.functionClickable = true;
						window.location.href="#"+selectHost.host+":"+selectHost.port;
					} else {
						redisVue.functionClickable = true;
						//alert("操作失败，请稍后重试!");
						addErrorTaost(redisVue,"操作失败，请稍后重试!");
					}
				})
				.catch(function (error) {
					redisVue.functionClickable = true;
					addErrorTaost(redisVue,'Error! Could not reach the API. ' + error);
				});
			},
			refreshDatabase: function () {
				if(!this.functionClickable) {
					alert("please wait for change host complete!");
					return;
				}
				initHostDataBase(this, this.currentDatabseIndex);
				refreshRedisKeyspace(this);
			},
			changeDataBase: function (database) {
				var redisVue = this;
				if (!redisVue.functionClickable) {
					alert("please wait for change host complete!");
					return;
				}
				initHostDataBase(this, database);
			},
			searchByRecent: function (searchpattern) {
				searchByrecentStr(this, searchpattern);
			},
			searchByKey: function () {
				searchByKey(this, true);
			},
			deleteByKey: function (delKey, index) {
				if(!this.functionClickable) {
					alert("please wait for change host complete!");
					return;
				}
				var confirmResult = confirm("确认删除？");
				if (!confirmResult) {
					return;
				}
				var redisVue = this;
				var params = new URLSearchParams();
				params.append("key", delKey);
				axios.post(hostname + "/jedis/del", params)
				.then(function (response) {
				 	if (response.data) {
				 		var chindex = redisVue.currentHostIndex;
						var chost = redisVue.hostList[chindex];
						chost.datas.datalist.splice(index, 1);
					} else {
						addErrorTaost(redisVue,"删除失败！");
					}
				})
				.catch(function (error) {
					addErrorTaost(redisVue,'Error! Could not reach the API. ' + error);
				});
				return;
			},
			searchFieldByKey: function(field) {
				var redisVue = this;
				var params = new URLSearchParams();
				params.append("fieldPatter", redisVue.viewData.searchKey);
				params.append("key", redisVue.viewData.key);
				params.append("type", redisVue.viewData.type);
				redisVue.displayLoadingAnimation = true;
				axios.post(hostname + "/jedis/getByType", params)
				.then(function (response) {
					var resData = response.data;
					redisVue.popWindow.windowContent=response.data;
					if (redisVue.viewData.type == 'hash' || redisVue.viewData.type == 'set') {
						redisVue.popWindow.windowContentCursor = resData.cursor;
					} else if (redisVue.viewData.type != 'string') {
						redisVue.popWindow.windowContentCursor = resData.length + 1;
					}
					addSuccessTaost(redisVue,"查询成功 ");
				})
				.catch(function (error) {
					addErrorTaost(redisVue,'Error! Could not reach the API. ' + error);
				});
			},
			viewByKey: function (key, index) {
				//alert(key);
				if(!this.functionClickable) {
					alert("please wait for change host complete!");
					return;
				}
				var redisVue = this;
				var keyType = redisVue.keyAndType[key];
				redisVue.viewData.key = key;
				if (keyType && keyType.length > 0 && !keyType.indexOf("none") < 0) {
					redisVue.viewData.type = keyType;
					viewKey(redisVue, key, keyType);
					return;
				}
				var params = new URLSearchParams();
				params.append("key", key);
				//var encodekey = encodeURIComponent(key);
				axios.post(hostname + "/jedis/type", params)
				.then(function (response) {
					if (!response.data) {
						addErrorTaost(redisVue, 'key not found!');
						return;
					}
					redisVue.keyAndType[key] = response.data;
					redisVue.viewData.type = redisVue.keyAndType[key];
					viewKey(redisVue, key, keyType);
				})
				.catch(function (error) {
					addErrorTaost(redisVue,'Error! Could not reach the API. ' + error);
				});
			},
			keyValueRefresh: function() {
				kvrefresh(this);
			},
			loadMoreKeys: function () {
				if(!this.functionClickable) {
					alert("please wait for change host complete!");
					return;
				}
				var redisVue = this;
				redisVue.displayLoadingAnimation = true;
				var chindex = redisVue.currentHostIndex;
				var chost = redisVue.hostList[chindex];
				var searchPattern = chost.searchKey;
				if (!searchPattern || searchPattern.length == 0) {
					searchPattern = "*";
				}
				var params = new URLSearchParams();
				params.append("keyPattern", searchPattern);
				axios.post(hostname + "/jedis/scan/" + chost.datas.nextIndex + "/", params)
				.then(function (response) {
					var resData = response.data;
					chost.datas.pageSize = resData.result.length;
					var oldDatas = chost.datas.datalist;
					chost.datas.datalist = oldDatas.concat(resData.result);
					chost.datas.nextIndex = resData.cursor;
					redisVue.displayLoadingAnimation = false;
				})
				.catch(function (error) {
					addErrorTaost(redisVue,'Error! Could not reach the API. ' + error);
				});
			},
			loadMoreValues: function() {
				var redisVue = this;
				var searchPattern = redisVue.viewData.searchKey;
				if (!searchPattern || searchPattern.length == 0) {
					searchPattern = "*";
				}
				var redisVue = this;
				redisVue.displayLoadingAnimation = true;
				var params = new URLSearchParams();
				params.append("fieldPatter", searchPattern);
				params.append("key", redisVue.viewData.key);
				params.append("type", redisVue.viewData.type);
				params.append("nextIndex", redisVue.popWindow.windowContentCursor);
				axios.post(hostname + "/jedis/getByType", params)
				.then(function (response) {
					var resData = response.data;
					if (redisVue.popWindow.windowContent['result']) {
						redisVue.popWindow.windowContent['result'] = redisVue.popWindow.windowContent['result'].concat(resData.result);
						redisVue.popWindow.windowContent['cursor'] = resData.cursor;
					} else {
						redisVue.popWindow.windowContent = redisVue.popWindow.windowContent.concat(resData);
					}
					if (redisVue.viewData.type == 'hash' || redisVue.viewData.type == 'set') {
						redisVue.popWindow.windowContentCursor = resData.cursor;
					} else if (redisVue.viewData.type != 'string') {
						redisVue.popWindow.windowContentCursor = redisVue.popWindow.windowContentCursor + resData.length;
					}
					redisVue.displayLoadingAnimation = false;
				})
				.catch(function (error) {
					addErrorTaost(redisVue,'Error! Could not reach the API. ' + error);
				});
			},
			deleteByField: function(obj, index) {
				//hash || set
				var confirmResult = confirm("确认删除？");
				if (!confirmResult) {
					return;
				}
				var redisVue = this;
				const viewType = redisVue.viewData.type;
				var params = new URLSearchParams();
				params.append("key", redisVue.viewData.key);
				if (viewType == "set") {
					params.append("member", obj);
					axios.post(hostname + "/jedis/sdel", params)
					.then(function (response) {
						kvrefresh(redisVue);
					})
					.catch(function (error) {
						addErrorTaost(redisVue, 'Error! Could not reach the API. ' + error);
					});
				} else if (viewType == "hash") {
					for(f in obj) {
						params.append("field", f);
					}
					axios.post(hostname + "/jedis/hdel", params)
					.then(function (response) {
						kvrefresh(redisVue);
					})
					.catch(function (error) {
						addErrorTaost(redisVue, 'Error! Could not reach the API. ' + error);
					});
				}
			},
			deleteByElement: function(obj, index) {
				//zset
				var confirmResult = confirm("确认删除？");
				if (!confirmResult) {
					return;
				}
				var redisVue = this;
				const viewType = redisVue.viewData.type;
				if (viewType == "zset") {
					var params = new URLSearchParams();
					params.append("key", redisVue.viewData.key);
					params.append("member", obj.element);
					axios.post(hostname + "/jedis/zdel", params)
					.then(function (response) {
						kvrefresh(redisVue);
					})
					.catch(function (error) {
						addErrorTaost(redisVue, 'Error! Could not reach the API. ' + error);
					});
				}
			},
			deleteByIndex: function (obj, index) {
				var confirmResult = confirm("确认删除？");
				if (!confirmResult) {
					return;
				}
				var redisVue = this;
				var params = new URLSearchParams();
				params.append("key", redisVue.viewData.key);
				params.append("member", obj);
				params.append("index", index);
				axios.post(hostname + "/jedis/ldel", params)
				.then(function (response) {
					kvrefresh(redisVue);
				})
				.catch(function (error) {
					addErrorTaost(redisVue, 'Error! Could not reach the API. ' + error);
				});
			},
			updateStringVal: function() {
				var redisVue = this;
				var params = new URLSearchParams();
				params.append("key", redisVue.viewData.key);
				params.append("value", redisVue.popWindow.windowContentNew);
				axios.post(hostname + "/jedis/set", params)
				.then(function (response) {
					kvrefresh(redisVue);
				})
				.catch(function (error) {
					addErrorTaost(redisVue, 'Error! Could not reach the API. ' + error);
				});
			},
			cancleUpdateStringVal: function() {
				this.$set(this.popWindow,"windowContentNew",this.popWindow.windowContent);
			},
			addValue: function() {
				var redisVue = this;
				var vd = redisVue.viewData;
				if (vd) {
					var params = new URLSearchParams();
					params.append("key", vd.key);
					var requetUrl = hostname + "/jedis";
					if (vd.type == 'zset') {
						params.append("value", vd.newValue);
						params.append("score", vd.newScore);
						requetUrl += "/zset";
					} else if (vd.type == 'hash') {
						params.append("value", vd.newValue);
						params.append("field", vd.newField);
						requetUrl += "/hset";
					} else if (vd.type == "list") {
						params.append("value", vd.newValue);
						requetUrl += "/rpush";
					} else if (vd.type == "set") {
						params.append("value", vd.newValue);
						requetUrl += "/sadd";
					}
					axios.post(requetUrl, params)
					.then(function (response) {
						kvrefresh(redisVue);
					})
					.catch(function (error) {
						addErrorTaost(redisVue, 'Error! Could not reach the API. ' + error);
					});
				} else {
					addErrorTaost(redisVue, '未知错误!');
				}
			}
		}
	});
</script>
</html>